#include "VoteKNN.h"
#include "VoteKNNSimWeight.h"

#include <algorithm>
#include <map>

using namespace std;

VoteKNN::VoteKNN()
{
}

VoteKNN::~VoteKNN()
{
}

VOID VoteKNN::deleteInstance(INOUT VOID* _ptr, IN STRING _insName, IN MemoryManager* _memM)
{
    if (_insName == VoteKNN::insName())
    {
        _memM->deleteT((VoteKNN*)_ptr);
    } 
    else if (_insName == VoteKNNSimWeight::insName())
    {
        _memM->deleteT((VoteKNNSimWeight*)_ptr);
    }
}

VoteKNN* VoteKNN::newInstance(IN STRING _insName, IN MemoryManager* _memM)
{
    if (_insName == VoteKNN::insName())
    {
        VoteKNN* ret = _memM->newT(ret);
        return ret;
    } 
    else if (_insName == VoteKNNSimWeight::insName())
    {
        VoteKNNSimWeight* ret = _memM->newT(ret);
        return ret;
    }
}

VoteKNN::W_VEC VoteKNN::vote(IN PriorityQueue& _pq, IN STRING _simName)
{
    W_VEC ret;
    typedef map<DOUBLE, DOUBLE> MAP;
    MAP count;

    for (UINT32 i = 0; i < _pq.size(); ++i)
    {
        DOUBLE lbl = _pq[i].label;
        INT c = 0;
        if (count.find(lbl) != count.end())
        {
            c = count[lbl];
        }
        count[lbl] = c + 1;
    }

    for (MAP::iterator ite = count.begin(); ite != count.end(); ++ite)
    {
        Weight w;
        w.label = (*ite).first;
        w.weight = (*ite).second * 1.0 / _pq.size();
        ret.push_back(w);
    }

    sort(ret.begin(), ret.end());

    return ret;
}